package com.serverlite.framework.dao.core;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.serverlite.framework.utils.JsonUtils;
import com.serverlite.framework.utils.StringUtils;

public class Dao extends D {
    
    public static String saveOrUpdate(String t, JSONObject o){
        String row_id = null;
        try{
            if(o.isNull("id")){
                row_id = Dao.insert(t, o);
            } else {
                Object id = o.get("id");
                if(id instanceof String && StringUtils.isEmpty(id.toString())){
                    row_id = Dao.insert(t, o);
                } else {
                    Dao.updateById(t, id, o);
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        return row_id;
    }

    public static String insert(String t, JSONObject o) throws JSONException {
        String id = UUID.randomUUID().toString();
        o.put("id", id);
        StringBuffer sql = insertSqlBuilder(t, o);
        D.update(sql.toString());
        return id;
    }

    public static void deleteById(String t, Object id) {
        D.update("delete from " + t + " where id=?", id);
    }

    public static void batchDeleteByIds(String t, String ids) {
        String[] idss = ids.split(",");
        Object[][] idsoo = new Object[idss.length][1];
        int index = 0;
        for (String id : idss) {
            idsoo[index] = new Object[] { id };
            index++;
        }
        D.batch("delete from " + t + " where id=?", idsoo);
    }

    public static void updateById(String t, Object id, JSONObject o) {
        StringBuffer sql = updateSqlBuilder(t, id, o);
        D.update(sql.toString());
    }

    public static Map<String, Object> selectById(String t, Object id) {
        Map<String, Object> map = D.queryById("select * from " + t
                + " where id=?", id);
        return map;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static JSONArray select(String sql, Object... params) {
        List<Object> list = (List)D.query(sql, params);
        if(list == null){
            return null;
        }
        return JsonUtils.listv2json(list);
    }
    
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static JSONArray selectAll(String t) {
        List<Object> list = (List)D.queryAll(t);
        if(list == null){
            return null;
        }
        return JsonUtils.listv2json(list);
    }

    public static JSONObject selectOne(String sql, Object... params) {
        Map<String, Object> map = D.queryOne(sql, params);
        if(map == null){
            return null;
        }
        return JsonUtils.map2json(map);
    }
    
    public static Page<Map<String, Object>> selectPage(String t, int pageNo,
            int pageSize) {
        return D.queryPage("select * from " + t, pageNo, pageSize);
    }

    public static Page<Map<String, Object>> selectPage(String t, String where, String sortField, String sortOrder, int pageNo,
            int pageSize) {
        if(!StringUtils.isEmpty(sortField) && !StringUtils.isEmpty(sortOrder) && !StringUtils.isEmpty(where)){
            return D.queryPage("select * from " + t + " where " + where + " order by " + sortField + " " + sortOrder, pageNo, pageSize);
        } else if(!StringUtils.isEmpty(sortField) && !StringUtils.isEmpty(sortOrder)){
            return D.queryPage("select * from " + t + " order by " + sortField + " " + sortOrder, pageNo, pageSize);
        } else if(!StringUtils.isEmpty(where)){
            return D.queryPage("select * from " + t + " where " + where, pageNo, pageSize);
        }
        return D.queryPage("select * from " + t , pageNo, pageSize);
    }
    
    public static Page<Map<String, Object>> selectPage(String sql, String sortField, String sortOrder, int pageNo,
            int pageSize) {
        if(!StringUtils.isEmpty(sortField) && !StringUtils.isEmpty(sortOrder)){
            return D.queryPage(sql + " order by " + sortField + " " + sortOrder, pageNo, pageSize);
        }
        return D.queryPage(sql, pageNo, pageSize);
    }
    
    private static StringBuffer insertSqlBuilder(String t, JSONObject o) {
        if (StringUtils.isEmpty(t)) {
            throw new RuntimeException("table is null!");
        }
        if (o == null || o.length() == 0) {
            throw new RuntimeException("object is null!");
        }
        StringBuffer sql = new StringBuffer("insert into ");
        StringBuffer valBuffer = new StringBuffer("values(");
        sql.append(t);
        sql.append("(");
        Iterator<?> iter = o.keys();
        try {
            while (iter.hasNext()) {
                String key = (String) iter.next();
                Object val = o.get(key);
                sql.append("`");
                sql.append(key);
                sql.append("`");
                sql.append(",");
                if (val instanceof String) {
                    valBuffer.append("'");
                    valBuffer.append(val);
                    valBuffer.append("',");
                } else {
                    valBuffer.append(val);
                    valBuffer.append(",");
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        if (sql.lastIndexOf(",") > 0) {
            sql.deleteCharAt(sql.lastIndexOf(","));
        }
        if (valBuffer.lastIndexOf(",") > 0) {
            valBuffer.deleteCharAt(valBuffer.length() - 1);
        }
        valBuffer.append(")");
        sql.append(") ").append(valBuffer);
        return sql;
    }
    
    private static StringBuffer updateSqlBuilder(String t, Object id,
            JSONObject o) {
        if (StringUtils.isEmpty(t)) {
            throw new RuntimeException("table is null!");
        }
        if (id == null) {
            throw new RuntimeException("id is null!");
        }
        if (o == null || o.length() == 0) {
            throw new RuntimeException("object is null!");
        }

        StringBuffer sqlBuffer = new StringBuffer("update ");
        sqlBuffer.append(t);
        sqlBuffer.append(" set ");
        
        Iterator<?> iter = o.keys();
        try {
            while (iter.hasNext()) {
                String key = (String) iter.next();
                Object val = o.get(key);
                sqlBuffer.append("`");
                sqlBuffer.append(key);
                sqlBuffer.append("`");
                sqlBuffer.append("=");
                if (val instanceof String) {
                    sqlBuffer.append("'");
                    sqlBuffer.append(val);
                    sqlBuffer.append("'");
                } else {
                    sqlBuffer.append(val);
                }
                sqlBuffer.append(", ");
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        if (sqlBuffer.lastIndexOf(",") > 0) {
            sqlBuffer.deleteCharAt(sqlBuffer.lastIndexOf(","));
        }

        sqlBuffer.append("where id=");
        if (id instanceof String) {
            sqlBuffer.append("'");
            sqlBuffer.append(id);
            sqlBuffer.append("'");
        } else {
            sqlBuffer.append(id);
        }
        return sqlBuffer;
    }    
    
}
